#ifndef _NG_MY_BASE_H
#define _NG_MY_BASE_H
#include <mysql.h>
#include <ng_sql.h>

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;

typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
typedef long long int64;


#define VOS_OK                          0
#define VOS_ERROR                       1
#define VOS_ERROR_START                 5000 

#define VOS_OS_ERR_START                (VOS_ERROR_START)		/*5000-5499*/
#define VOS_NETWORK_ERR_START           (VOS_ERROR_START + 500)		/*5500-6499*/
#define VOS_PTHREAD_ERR_START           (VOS_NETWORK_ERR_START + 1000)	/*6500-6999*/		
#define VOS_USR_ERR_START               (VOS_PTHREAD_ERR_START + 500)	/*7000-7999*/
#define VOS_SQL_ERR_START               (VOS_USR_ERR_START + 1000)	/*8000-8999*/
#define VOS_ROUTE_ERR_START             (VOS_SQL_ERR_START + 1000)	/*9000-*/

#define VOS_OS_ERR_MALLOC_FAIL                          (VOS_OS_ERR_START + 1)
/*begin: add by wangtianyu for mem 201201123*/
#define VOS_OS_ERR_MALLOC_FAIL                          (VOS_OS_ERR_START + 1)  //5001
#define VOS_OS_ERR_POINTER_NULL                         (VOS_OS_ERR_START + 2)
#define VOS_OS_ERR_MALLOC_PAGE_FAIL                     (VOS_OS_ERR_START + 3)
#define VOS_OS_ERR_MALLOC_BLOCK_FAIL                    (VOS_OS_ERR_START + 4)
#define VOS_OS_ERR_MEM_BLOCK_MIN_FULL                   (VOS_OS_ERR_START + 5)
#define VOS_OS_ERR_MEM_BLOCK_LESS_FULL                  (VOS_OS_ERR_START + 6)
#define VOS_OS_ERR_MEM_BLOCK_MORE_FULL                  (VOS_OS_ERR_START + 7)
#define VOS_OS_ERR_MEM_BLOCK_MAX_FULL                   (VOS_OS_ERR_START + 8)
#define VOS_OS_ERR_MEM_LOOP_FULL                        (VOS_OS_ERR_START + 9)
#define VOS_OS_ERR_MEM_MALLOC_NO_OK                     (VOS_OS_ERR_START + 10)
#define VOS_OS_ERR_MEM_INIT_NO_OK                       (VOS_OS_ERR_START + 11)
#define VOS_OS_ERR_MEM_MALLOC_SIZE_INVAILD              (VOS_OS_ERR_START + 12)
#define VOS_OS_ERR_MEM_NODE_SIZE_ZERO                   (VOS_OS_ERR_START + 13)
/*end: add by wangtianyu for mem 201201123*/

/*begin: add by shell for configration init 20121205*/
#define VOS_OS_ERR_START_IP_ERR  	           	(VOS_ERROR_START + 21)
#define VOS_OS_ERR_START_ARGUMENT       	      	(VOS_ERROR_START + 22)
/*end: add by shell for configration init 20121205*/

#define VOS_NETWORK_ERR_CONNECT_FAIL                    (VOS_NETWORK_ERR_START + 1)  //5501
#define VOS_NETWORK_ERR_NET_VIO_ERR                     (VOS_NETWORK_ERR_START + 2)
#define VOS_NETWORK_ERR_POINTER_NULL                    (VOS_NETWORK_ERR_START + 3) 

#define VOS_PTHREAD_ERR_ID_INVAILD                      (VOS_PTHREAD_ERR_START + 1)  //6501
#define VOS_PTHREAD_ERR_PTHREAD_NUM_OVER                (VOS_PTHREAD_ERR_START + 2) 
#define VOS_PTHREAD_ERR_PTHREAD_FREE_LINK_EMPTY         (VOS_PTHREAD_ERR_START + 3) 
#define VOS_PTHREAD_ERR_PTHREAD_READY_LINK_EMPTY        (VOS_PTHREAD_ERR_START + 4) 
#define VOS_PTHREAD_ERR_PTHREAD_POINTER_NULL            (VOS_PTHREAD_ERR_START + 5) 
#define VOS_PTHREAD_ERR_PTHREAD_NUM_OVERRUN             (VOS_PTHREAD_ERR_START + 6) 

#define VOS_SQL_ERR_POINTER_NULL                        (VOS_SQL_ERR_START + 1)   //8001
#define VOS_SQL_ERR_DB_IS_NOT_EXIST                     (VOS_SQL_ERR_START + 2) 
#define VOS_SQL_ERR_TABLE_IS_NOT_EXIST                  (VOS_SQL_ERR_START + 3) 
#define VOS_SQL_ERR_TABLE_HASH_MOD_INVAILD              (VOS_SQL_ERR_START + 4)
#define VOS_SQL_ERR_TABLE_INCLU_STRING                  (VOS_SQL_ERR_START + 5) 
#define VOS_SQL_ERR_INVAILD_KEY_RELATION                (VOS_SQL_ERR_START + 6) 
#define VOS_SQL_ERR_TABLE_HASH_MOD_OVERRUN              (VOS_SQL_ERR_START + 7)
#define VOS_SQL_ERR_MORE_CHILD_DB                       (VOS_SQL_ERR_START + 8)
#define VOS_SQL_ERR_KEY_TYPE_ERR                        (VOS_SQL_ERR_START + 9)
#define VOS_SQL_ERR_TABLE_NAME_ERR                      (VOS_SQL_ERR_START + 10)
#define VOS_SQL_ERR_DB_IS_NOT_USED                      (VOS_SQL_ERR_START + 11) 
#define VOS_SQL_ERR_VALUE_INVAILD                       (VOS_SQL_ERR_START + 12) 
#define VOS_SQL_ERR_SQL_LENGTH_INVAILD                  (VOS_SQL_ERR_START + 13) 

/*BEGIN add by oxwf 2012-11-14*/
#define VOS_SQL_ERR_NO_KEY                              (VOS_SQL_ERR_START + 101)//sql语句中查询不到主键    4101
#define VOS_SQL_ERR_GRAMMAR	                       		(VOS_SQL_ERR_START + 102)//where子句中犯的语法错误返回这个
#define VOS_SQL_ERR_NO_KEY_COL							(VOS_SQL_ERR_START + 103)//在insert语句中使用，查询不到主键所在的列号
#define VOS_SQL_ERR_NO_SUPPORT                          (VOS_SQL_ERR_START + 104)//不支持这种sql语句
#define VOS_SQL_ERR_NO_SUPPORT_ITEM						(VOS_SQL_ERR_START + 105)//where 字句中不支持的item
#define VOS_SQL_ERR_NO_SUPPORT_SQL_COMMAND				(VOS_SQL_ERR_START + 106)//不支持的sql命令
#define VOS_SQL_ERR_AUTOINCRCOL_ISNOT_KEY				(VOS_SQL_ERR_START + 107)//自增长列不是主键
#define VOS_SQL_ERR_NO_SUPPORT_FUNTION_ITEM      	    (VOS_SQL_ERR_START + 108)
#define VOS_SQL_ERR_OUT_MOD                             (VOS_SQL_ERR_START + 109)//不支持这种sql语句
#define VOS_SQL_ERR_SEQUENCE		                    (VOS_SQL_ERR_START + 110)//不支持这种sql语句
#define VOS_SQL_ERR_RECONFIGING		                    (VOS_SQL_ERR_START + 111)//�����������ã����Ժ�����
#define VOS_SQL_SEND_TO_CLIENT_FAILED		          	(VOS_SQL_ERR_START + 112)//�����������ã����Ժ�����
#define VOS_SQL_NOT_A_SELECT	                    	(VOS_SQL_ERR_START + 113)//�����������ã����Ժ�����
#define VOS_SQL_SELECT_SHOULD_RETURN_DATA              	(VOS_SQL_ERR_START + 114)//�����������ã����Ժ�����
/*END add by oxwf 2012-11-14*/

/* END add by shell 2012-12-05 */

#define MAX_UINT32_VALUE     0xFFFFFFFF
#define MAX_UINT16_VALUE     0xFFFF
#define MAX_UINT8_VALUE      0xFF

/*BEGIN: modified by qinbo for add reload configuration*/
#define HASH_MOD  16
/*END: modified by qinbo for add reload configuration*/
#define DB_NUM    3

/* max connections per child db */
#define MAX_CHILD_DB_THREAD_NUM (4092 + 1)
/* max connections per db */
#define MAX_DB_THREAD_NUM (HASH_MOD * MAX_CHILD_DB_THREAD_NUM)
/* max connections of jdbd */
#define THREAD_ELEM_NUM  (DB_NUM * MAX_DB_THREAD_NUM + 20)

#define TABLE_NAME_LENGTH 32
#define KEY_NAME_LENGTH 32

#define IP_ADDRESS_LENGTH 15
#define DB_ADMIN_NAME_LENGTH 15
#define DB_ADMIN_PWD_LENGTH 15

#define DB_NAME_LENGTH 15
#define TABLE_NUM 128
#define MAX_CHILD_TABLE_PER 64 

/*modify by oxwf just for support the time, the time string length is 19*/
#define HASH_MOD_STRING_LENGTH 20  

#define KEY_VALUE_LENGTH 32
#define KEY_MAX_NUM      10


#define MYSQL_RESULT_HEAD_SIZE       18
#define MYSQL_RESULT_FIELD_SIZE      1024
#define MYSQL_GET_READY_TIMES        5
#define MYSQL_INIT_READY_LINK_NUM    2

/*begin: add by wangtianyu for mem 201201123*/
#define MEM_NODE_MIN_SIZE     256
#define MEM_NODE_LESS_SIZE    1024
#define MEM_NODE_MORE_SIZE    (1024 * 8)
#define MEM_NODE_MAX_SIZE     (1024 * 256)

#define MEM_NODE_MIN_NUM      65536
#define MEM_NODE_LESS_NUM     6144
#define MEM_NODE_MORE_NUM     1024
#define MEM_NODE_MAX_NUM      8
#if 0
#define MEM_NODE_MIN_NUM      40 
#define MEM_NODE_LESS_NUM     10 
#define MEM_NODE_MORE_NUM     5 
#define MEM_NODE_MAX_NUM      2
#endif
#define MEM_PAGE_HEAD_SIZE    sizeof(st_MEM_Page_M)
#define MEM_BLOCK_HEAD_SIZE   sizeof(st_MEM_Block_M)
#define MEM_NODE_HEAD_SIZE    sizeof(st_MEM_Node_M)
#define MEM_POINT_SIZE        sizeof(void *)


#define MEM_NODE_MIN_TYPE     1
#define MEM_NODE_LESS_TYPE    2
#define MEM_NODE_MORE_TYPE    3
#define MEM_NODE_MAX_TYPE     4

#define MEM_MAX_PAGE_NUM      640
#define MEM_INIT_PAGE_NUM     64
#define MEM_NORMAL_PAGE_NUM   160   
#define MEM_LOOP_EACH_TIME    MEM_INIT_PAGE_NUM   
#define MAX_CACHE_ROW_RESULTS 32
/*end: add by wangtianyu for mem 201201123*/
#define MAX_DB_HASH_MOD       32

/*begin: add by oxwf for log 201201207*/
#define LOG_DIR_NAME_LENGTH 512
#define LOG_FILE_NAME_LENGTH 512
#define NG_LOG_BUF_SIZE  (1024*1024*10)

/*end: add by oxwf for log 201201207*/

enum Type {
    FIELD_ITEM = 0, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
    INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
    COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
    PROC_ITEM, COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
    FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
    SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
    PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
    XPATH_NODESET, XPATH_NODESET_CMP,
    VIEW_FIXER_ITEM
};

enum Functype {
    UNKNOWN_FUNC, EQ_FUNC, EQUAL_FUNC, NE_FUNC, LT_FUNC, LE_FUNC,
    GE_FUNC, GT_FUNC, FT_FUNC,
    LIKE_FUNC, ISNULL_FUNC, ISNOTNULL_FUNC,
    COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
    BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
    INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
    SP_EQUALS_FUNC, SP_DISJOINT_FUNC, SP_INTERSECTS_FUNC,
    SP_TOUCHES_FUNC, SP_CROSSES_FUNC, SP_WITHIN_FUNC,
    SP_CONTAINS_FUNC, SP_OVERLAPS_FUNC,
    SP_STARTPOINT, SP_ENDPOINT, SP_EXTERIORRING,
    SP_POINTN, SP_GEOMETRYN, SP_INTERIORRINGN,
    NOT_FUNC, NOT_ALL_FUNC,
    NOW_FUNC, TRIG_COND_FUNC,
    SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
    EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
    NEG_FUNC, GSYSVAR_FUNC
};

typedef struct st_thread_m {
    uint32 connect_id;
    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

    uint8 status; /*0:free, 1:ready, 2:active*/
    uint8 position; /*0:default, 1:front, 2:back */
    uint8 priority; /*0-9, default is 0 , 线程的权重*/
    uint8 reserved4;

    uint8 db_id;
    uint8 child_db_id;
    uint8 reserved5;
    uint8 reserved6;

    MYSQL mysql;

    int data;
    struct st_thread_m *next;

    uint32 max_mem; /*记录该线程最大处理的一次请求结果占用空间大小*/
    uint32 rw_flag;
} st_Thread_M;

/*分库线程结构*/
typedef struct st_ThreadPool {
    uint8 child_db_id;
    uint8 priority;
    uint32 threadnum;
    uint32 thread_maxnum;
    mysql_mutex_t lock_thdpool_data;
    st_Thread_M *ready_h;
    st_Thread_M *ready_t;

} st_ThreadPool;

/*某库线程池的结构*/
typedef struct st_ThreadPool_m {
    uint8 db_id; /*db id*/
    uint8 position; /*front:1 back:2 default:0*/
    uint8 db_hash_mod; /*该库拆表取模值，用于校验拆表MOD*/
    uint8 reserved1;

    st_ThreadPool thread_pool[HASH_MOD];
} st_ThreadPool_M;


/*begin 数据库配置信息*/

/*某库的中指定表的信息*/
typedef struct st_Table_m {
    char table_name[TABLE_NAME_LENGTH + 1]; /*表名*/
    char key_name[KEY_NAME_LENGTH + 1]; /*主键名称*/

    uint8 table_hash_mod; /*该表拆分情况*/
    uint8 key_type; /*主键类型1:字符串2:数字*/
    uint8 key_col; /*主键所在列*/
    /*add by oxwf in 2013.2.25*/
    char sequence_name[KEY_NAME_LENGTH + 1]; /* Increment column name */
    /******END*****************/

    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

} st_Table_m;

typedef struct st_Slave_Info {
    char slave_db_name[DB_NAME_LENGTH + 1]; /*slave's database name*/
    char slave_host[IP_ADDRESS_LENGTH + 1]; /*slave's IP*/
    uint slave_port; /*slave's port*/
    char slave_user[DB_ADMIN_NAME_LENGTH + 1]; /*slave's user */
    char slave_pwd[DB_ADMIN_PWD_LENGTH + 1]; /*slave's password*/
    uint slave_status; /*slave's status. if can be used .  1 is good*/

} st_Slave_Info;

/* */
typedef struct st_ChildDbInfo {
    char child_db_name[DB_NAME_LENGTH + 1]; /*数据库分库名�*/
    char host[IP_ADDRESS_LENGTH + 1]; /*中间件连接DB的IP*/
    uint port; /*中间件连接DB的port*/

    char user[DB_ADMIN_NAME_LENGTH + 1]; /*中间件连接DB的user */
    char pwd[DB_ADMIN_PWD_LENGTH + 1]; /*中间件连接DB的pwd*/
    ulong client_flag;

    char used; /*是否使用，0：未使用，1使用*/
    uint32 thread_maxnum;
    uint8 reserved1;

    uint8 slave_num; /*slave数量*/
    st_Slave_Info slave_cluster[2]; /* */
} st_child_DBInfo;

typedef struct st_DbInfo {
    char db_name[DB_NAME_LENGTH + 1]; /* database name */
    uint8 db_id; /* database id */
    uint8 db_hash_mod; /* group hash mod */

    char used; /* remark，0：unused，1 used*/
    uint8 reserved1;
    uint8 hash_info[MAX_DB_HASH_MOD];

    st_Table_m table_list[TABLE_NUM]; /*库中的原表信息数组，即有多少张表*/
    st_child_DBInfo child_DbInfo_list[HASH_MOD];
} st_DBInfo;

/*end  ng proxy configuration information */

typedef struct st_child_db_stat {
    uint64 select_sql;
    uint64 insert_sql;
    uint64 update_sql;
    uint64 delete_sql;

    uint64 select_sql_ok;
    uint64 insert_sql_ok;
    uint64 update_sql_ok;
    uint64 delete_sql_ok;
} st_child_db_stat;

typedef struct st_DB_stat {
    uint64 select_sql;
    uint64 insert_sql;
    uint64 update_sql;
    uint64 delete_sql;

    st_child_db_stat child_DbInfo_list[HASH_MOD];
} st_DB_stat;

union sql_key_value {
    int64 key_value_int[KEY_MAX_NUM];
    char key_value_str[KEY_MAX_NUM][KEY_VALUE_LENGTH + 1];
    float key_value_float[KEY_MAX_NUM];
    double key_value_double[KEY_MAX_NUM];
};

typedef struct st_HandleSql_Info {
    char db_name[DB_NAME_LENGTH + 1];
    char table_name[TABLE_NAME_LENGTH + 1];
    uint8 table_hash_mod;
    uint8 reserved1;
    uint8 reserved2;
    uint8 reserved3;

    char key_name[KEY_NAME_LENGTH + 1];

    uint16 key_relation;
    uint8 key_value_num;
    uint8 key_type;
    union sql_key_value key_value;
    /******************************************/
    char sequence_name[KEY_NAME_LENGTH + 1];
    /******************************************/
} st_HandleSql_Info;

/*begin: add by wangtianyu for mem 201201123*/
typedef struct st_MEM_Malloc_Info {
    uint32 min_num;
    uint32 less_num;
    uint32 more_num;
    uint32 max_num;
} st_MEM_Malloc_Info;

typedef struct st_MEM_Node_M {
    uint16 page_index;
    uint8 type;
    uint8 state;

    uint32 node_index;
    uint32 node_next;
    void * base;
} st_MEM_Node_M;

typedef struct st_MEM_Block_M {
    uint32 node_n;
    uint32 free;
    uint32 free_n;
    uint32 tail;

    mysql_mutex_t lock_mem_block_data;
    uint32 used_node_num;
    void * base;

} st_MEM_Block_M;

typedef struct st_MEM_Page_M {
    uint32 page_index;

    st_MEM_Block_M min_blk_m;
    st_MEM_Block_M less_blk_m;
    st_MEM_Block_M more_blk_m;
    st_MEM_Block_M max_blk_m;

} st_MEM_Page_M;
/*end: add by wangtianyu for mem 201201123*/

extern st_Thread_M g_thread_elem_m[THREAD_ELEM_NUM]; /* thread unit management */
extern st_Thread_M *pst_thread_elem_free_h;
extern st_Thread_M *pst_thread_elem_free_t;

extern st_ThreadPool_M g_back_threadpool[DB_NUM]; /* thread backend management */

extern uint32 g_back_thread_count;

extern st_DBInfo st_DB_Info[DB_NUM];
extern st_DB_stat st_DB_sql_stat[DB_NUM];
extern uint32 g_pthread_pool_init_flag;


/*BEGIN ADD BY oxwf in 2012.11.28*/
extern char ng_log_file_path[LOG_DIR_NAME_LENGTH];
extern char ng_log_file_name[LOG_FILE_NAME_LENGTH];
// ng log
extern uint8 ng_debug_log_on;
extern uint8 ng_info_log_on;
extern uint8 ng_warn_log_on;
extern uint8 ng_error_log_on;
extern uint8 ng_printf_on;
// archive log everyday
extern uint day_log_flag;
/*END ADD BY oxwf in 2012.11.28*/

/*begin: add by wangtianyu for mem 201201123*/
extern st_MEM_Page_M *pst_mem_page_list[MEM_MAX_PAGE_NUM];
extern st_MEM_Malloc_Info malloc_size;
extern uint32 g_page_used_index;
extern uint8 malloc_more_page_flag;
extern uint32 g_mem_max_page_num;
extern uint32 mem_init_page_num;
extern uint32 g_mem_max_cache_row_results;
/*end: add by wangtianyu for mem 201201123*/
extern char *my_data;

/*begin: add by wangtianyu for mem 201201123*/
extern void show_mem();
extern st_MEM_Page_M * Mem_Malloc_One_Page_NOLOCK(st_MEM_Malloc_Info malloc_size, uint32 *stat);
extern char * Mem_Malloc(uint32 size, THD *thd);
extern void Mem_Free(char *ptr);
extern uint32 Do_Mysql_Middle_Dis(THD *thd, st_HandleSql_Info *info, char *query);
extern uint32 Do_Mysql_Middle_Set(THD *thd, st_HandleSql_Info *info, char *query);
/*end: add by wangtianyu for mem 201201123*/

extern void show_link();
extern uint32 Put_Thread_Into_Ready_NOLOCK(st_Thread_M *pstThread_m);
extern uint32 Put_Thread_Into_Free_NOLOCK(st_Thread_M *pstThread_m);
extern st_Thread_M * Get_Thread_From_Free_NOLOCK(uint8 db_id, uint8 child_db_id, uint32 *stat);

extern uint32 Put_Thread_Into_Ready(st_Thread_M *pstThread_m);
extern uint32 Put_Thread_Into_Free(st_Thread_M *pstThread_m);
extern st_Thread_M * Get_Thread_From_Free(uint8 db_id, uint8 child_db_id, uint32 *stat);
extern st_Thread_M * Get_Thread_From_Ready(uint8 db_id, uint8 child_db_id, uint32 *stat);

extern MYSQL * STDCALL Mysql_Create_Connect(MYSQL *mysql, st_child_DBInfo child_db_info, uint32 rw_flag);
extern uint32 Get_DB_Id(char * db_name, uint8 *db_id);
extern uint32 Get_Table_Info(uint8 db_id, char *table_name, char *key_name,
        uint8 *key_type, uint8 *tl_hash_mod, uint8 *key_col, char *auto_increate_col);

/**oxwf in 2013.2.26*/
extern uint32 Get_Route_Result(uint8 db_id, st_HandleSql_Info *handle_sql_info,
        uint8 table_num, uint8 *new_table_id, uint8 *child_db_id, uint8 *count, uint8 insert_flag);
extern uint32 Update_Table_Name(char *sql, st_HandleSql_Info *handle_sql_info, uint8 table_num, uint8 child_db_id, uint32 *query_length);
extern st_Thread_M * Get_ONE_Thread_M(uint8 db_id, uint8 child_db_id, uint32 *stat, uint32 rw_flag);


extern uint32 Do_Mysql_Query_NoResult(THD *thd, MYSQL *mysql, char *query, uint32 *ng_affect_rows);
extern uint32 Do_Mysql_Query_WithResult(THD *thd, MYSQL *mysql, char *query, st_Thread_M *pstThread_m);
/**oxwf in 2013.2.26*/
extern uint32 Do_Mysql_Query_WithResult2(THD *thd, MYSQL *mysql, char *query, st_Thread_M *pstThread_m, uint8 temp);
extern bool net_send_eof(THD *thd, uint server_status, uint statement_warn_count);

#endif /* _NG_MY_BASE_H */
